package com.info.zhiduoduo.core.service.common;

import com.github.pagehelper.Page;
import com.info.zhiduoduo.common.constants.SmartResult;
import com.info.zhiduoduo.common.constants.StatusMsg;
import com.info.zhiduoduo.common.exception.SmartException;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.transaction.PlatformTransactionManager;
import org.springframework.transaction.TransactionStatus;
import org.springframework.transaction.support.DefaultTransactionDefinition;

import java.io.IOException;
import java.io.OutputStream;
import java.net.URLEncoder;
import java.util.List;

import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletResponse;

import lombok.extern.slf4j.Slf4j;

@Slf4j
public class BaseService {

	@Autowired
	private PlatformTransactionManager transactionManager;

	public SmartResult smartResult() {
		return new SmartResult();
	}

	public SmartResult smartResult(StatusMsg statusMsg) {
		SmartResult smartResult = new SmartResult();
		smartResult.setStateMsg(statusMsg);
		return smartResult;
	}

	public SmartResult smartResult(int status, String msg) {
		SmartResult smartResult = smartResult();
		smartResult.setState(status);
		smartResult.setMsg(msg);
		return smartResult;
	}

	public SmartResult errorParamSmartResult() {
		return smartResult(StatusMsg.StatusMsg_101);
	}

	public SmartResult emptyDataSmartResult() {
		return smartResult(StatusMsg.StatusMsg_102);
	}

	public SmartResult optFailSmartResult() {
		return smartResult(StatusMsg.StatusMsg_199);
	}

	public <T> SmartResult<T> smartResult(T t) {
		SmartResult smartResult = smartResult();
		smartResult.setObject(t);
		return smartResult;
	}

	public <T> SmartResult<T> smartResult(List<T> list) {
		SmartResult<T> smartResult = smartResult();
		smartResult.setList(list);
		return smartResult;
	}

	public <T> SmartResult<T> smartResult(List<T> list, long totalRecords, int totalPages, int currPage) {
		SmartResult smartResult = smartResult();
		smartResult.setList(list);
		smartResult.setTotalrecords((int) totalRecords);
		smartResult.setTotalpages(totalPages);
		smartResult.setCurrpage(currPage);
		return smartResult;
	}

	public <T> SmartResult<T> smartResultAll(List<T> list, long totalRecords, int totalPages, int currPage, Object object) {
		SmartResult smartResult = smartResult();
		smartResult.setList(list);
		smartResult.setTotalrecords((int) totalRecords);
		smartResult.setTotalpages(totalPages);
		smartResult.setCurrpage(currPage);
		smartResult.setObject(object);
		return smartResult;
	}

	public <T> SmartResult<T> smartResultPage(Page<T> page) {
		return smartResult(page.getResult(), page.getTotal(), page.getPages(), page.getPageNum());
	}

	public <T> SmartResult<T> smartResultPageAndObject(Page<T> page, Object object) {
		return smartResultAll(page.getResult(), page.getTotal(), page.getPages(), page.getPageNum(), object);
	}

	public void returnResponse(ServletResponse response, SmartResult smartResult) {
		response.setContentType("application/json");
		response.setCharacterEncoding("UTF-8");
		try {
			response.getWriter().write(smartResult.toString());
			response.getWriter().flush();
			response.getWriter().close();
		} catch (IOException e) {
			e.printStackTrace();
		}
	}

	public void returnResponse(ServletResponse response, StatusMsg statusMsg) {
		response.setContentType("application/json");
		response.setCharacterEncoding("UTF-8");
		try {
			response.getWriter().write(smartResult(statusMsg).toString());
			response.getWriter().flush();
			response.getWriter().close();
		} catch (IOException e) {
			e.printStackTrace();
		}
	}

	/**
	 * 获取输出流，并设置下载excel的header
	 *
	 * @param response
	 * @param file
	 * @return
	 * @throws Exception
	 */
	public OutputStream getExcelOutPutStream(HttpServletResponse response, String file) throws Exception {
		// 这里注意 有同学反应使用swagger 会导致各种问题，请直接用浏览器或者用postman
		response.setContentType("application/vnd.ms-excel");
		response.setCharacterEncoding("utf-8");
		// 这里URLEncoder.encode可以防止中文乱码 当然和easyexcel没有关系
		String fileName = URLEncoder.encode(file, "UTF-8");
		response.setHeader("Content-disposition", "attachment;filename=" + fileName + ".xlsx");
		return response.getOutputStream();
	}

	/**
	 * 手动提交事务的快捷方法。
	 *
	 * @param run 需要执行的业务逻辑
	 * @return
	 */
	public SmartResult transact(Runnable run) {
		TransactionStatus status = transactionManager.getTransaction(new DefaultTransactionDefinition());
		try {
			run.run();
			transactionManager.commit(status);
			return SmartResult.success();
		} catch (SmartException se) {
			transactionManager.rollback(status);
			log.error("提交事务报错:", se);
			return SmartResult.fail(se.getState(), se.getMsg()).setObject(se.getData()).setList(se.getList());
		} catch (Exception e) {
			transactionManager.rollback(status);
			log.error("提交事务报错:", e);
			return SmartResult.fail(e.getMessage());
		}

	}
}
